package com.njtoyo.taxi.admin.service.business.operation_rule.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.njtoyo.taxi.admin.cache.PrimaryCachePutter;
import com.njtoyo.taxi.admin.library.common.OperationRecordHelper;
import com.njtoyo.taxi.admin.library.common.util.CopyUtil;
import com.njtoyo.taxi.admin.mapper.master.entity.Company;
import com.njtoyo.taxi.admin.mapper.master.entity.DriverRegionServiceArrangement;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoDriverRegion;
import com.njtoyo.taxi.admin.mapper.master.enums.DriverRegionServiceArrangementCategory;
import com.njtoyo.taxi.admin.mapper.master.fields.operation_rule.DriverFeeRate;
import com.njtoyo.taxi.admin.mapper.master.mapper.CompanyMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverRegionServiceArrangementMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoDriverRegionMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.operation_rule.DriverFeeRateInfoPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.operation_rule.DriverFeeRateCreateWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.operation_rule.DriverFeeRateUpdateWrapper;
import com.njtoyo.taxi.admin.service.business.operation_rule.DriverFeeRateService;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import com.njtoyo.taxi.entity.backend.AdminUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class DriverFeeRateServiceImpl implements DriverFeeRateService {
    
    @Autowired
    private GeoDriverRegionMapper geoDriverRegionMapper;
    
    @Autowired
    private DriverRegionServiceArrangementMapper driverRegionServiceArrangementMapper;
    
    @Autowired
    private CompanyMapper companyMapper;
    
    @Autowired
    private PrimaryCachePutter primaryCachePutter;
    
    @Autowired
    private OperationRecordHelper operationRecordHelper;
    
    @Override
    public RestResult<List<DriverFeeRateInfoPresenter>> all(AdminUser adminUser) {
        List<DriverRegionServiceArrangement> arrangements = driverRegionServiceArrangementMapper.getListByCategory(DriverRegionServiceArrangementCategory.fee_rate);
        List<DriverFeeRateInfoPresenter> res = new ArrayList<>();
        
        for (DriverRegionServiceArrangement arrangement : arrangements) {
            DriverFeeRate rate = JSONUtil.toBean(arrangement.getDetailSpecification(), DriverFeeRate.class);
            DriverFeeRateInfoPresenter info = CopyUtil.copy(rate.getGeneral(), DriverFeeRateInfoPresenter.class);
            info.setDriverRegionId(arrangement.getDriverRegionId())
                    .setIsOpen(arrangement.getIsOpen());
            res.add(info);
            if (Objects.nonNull(rate.getSpecial())) {
                for (DriverFeeRate.Special special : rate.getSpecial()) {
                    info = CopyUtil.copy(special, DriverFeeRateInfoPresenter.class);
                    info.setDriverRegionId(arrangement.getDriverRegionId())
                            .setCompanyId(special.getCompanyId())
                            .setIsOpen(arrangement.getIsOpen());
                    res.add(info);
                }
            }
        }
        return RestResult.success(res);
    }

    @Override
    public RestResult create(AdminUser adminUser, DriverFeeRateCreateWrapper wrapper) {
        GeoDriverRegion driverRegion = geoDriverRegionMapper.selectById(wrapper.getDriverRegionId());
        if (Objects.isNull(driverRegion)) {
            return RestResult.failed("司机运营区不存在");
        }
        DriverRegionServiceArrangement arrangement = driverRegionServiceArrangementMapper.selectByCategoryAndDriverRegionId(DriverRegionServiceArrangementCategory.fee_rate, wrapper.getDriverRegionId());
        if (Objects.nonNull(arrangement)) {
            return RestResult.failed("配置已存在");
        }
        DriverFeeRate fee = wrapper.getDetailSpecification();
        if (fee.getGeneral().getDriverEarningRatio().add(fee.getGeneral().getCompanyEarningRatio()).compareTo(BigDecimal.ONE) > 0) {
            return RestResult.failed("司机分成比和公司分成比不能超过1");
        }
        if (Objects.nonNull(fee.getSpecial())) {
            List<Long> companyIds = fee.getSpecial().stream().map(DriverFeeRate.Special::getCompanyId).collect(Collectors.toList());
            QueryWrapper<Company> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", companyIds)
                    .eq("driver_region_id", wrapper.getDriverRegionId());
            Integer count = companyMapper.selectCount(queryWrapper);
            if (count != fee.getSpecial().size()) {
                return RestResult.failed("存在非法公司");
            }
            for (DriverFeeRate.Special special : fee.getSpecial()) {
                if (special.getDriverEarningRatio().add(special.getCompanyEarningRatio()).compareTo(BigDecimal.ONE) > 0) {
                    return RestResult.failed("司机分成比和公司分成比不能超过1");
                }
            }
        }
        DriverRegionServiceArrangement arrangement1 = new DriverRegionServiceArrangement();
        arrangement1.setDriverRegionId(wrapper.getDriverRegionId())
                .setIsOpen(wrapper.getIsOpen())
                .setServiceCategory(DriverRegionServiceArrangementCategory.fee_rate)
                .setDetailSpecification(JSONUtil.toJsonStr(wrapper.getDetailSpecification()));
        driverRegionServiceArrangementMapper.insert(arrangement1);
        primaryCachePutter.deleteDriverServiceArrangement();
        operationRecordHelper.addBusinessLog(String.format("新增手续费规则 [%s]", arrangement1));
        return RestResult.success();
    }

    @Override
    public RestResult update(AdminUser adminUser, Long id, DriverFeeRateUpdateWrapper wrapper) {
        DriverRegionServiceArrangement arrangement = driverRegionServiceArrangementMapper.selectByCategoryAndId(DriverRegionServiceArrangementCategory.fee_rate, id);
        if (Objects.isNull(arrangement)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        DriverFeeRate fee = wrapper.getDetailSpecification();
        if (Objects.nonNull(fee)) {
            if (fee.getGeneral().getDriverEarningRatio().add(fee.getGeneral().getCompanyEarningRatio()).compareTo(BigDecimal.ONE) > 0) {
                return RestResult.failed("司机分成比和公司分成比不能超过1");
            }
            if (Objects.nonNull(fee.getSpecial())) {
                List<Long> companyIds = fee.getSpecial().stream().map(DriverFeeRate.Special::getCompanyId).collect(Collectors.toList());
                QueryWrapper<Company> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("id", companyIds)
                        .eq("driver_region_id", arrangement.getDriverRegionId());
                Integer count = companyMapper.selectCount(queryWrapper);
                if (count != fee.getSpecial().size()) {
                    return RestResult.failed("存在非法公司");
                }
                for (DriverFeeRate.Special special : fee.getSpecial()) {
                    if (special.getDriverEarningRatio().add(special.getCompanyEarningRatio()).compareTo(BigDecimal.ONE) > 0) {
                        return RestResult.failed("司机分成比和公司分成比不能超过1");
                    }
                }
            }
        }
        
        new LambdaUpdateChainWrapper<>(driverRegionServiceArrangementMapper)
                .eq(DriverRegionServiceArrangement::getId, id)
                .set(Objects.nonNull(wrapper.getIsOpen()), DriverRegionServiceArrangement::getIsOpen, wrapper.getIsOpen())
                .set(Objects.nonNull(wrapper.getDetailSpecification()), DriverRegionServiceArrangement::getDetailSpecification, JSONUtil.toJsonStr(wrapper.getDetailSpecification()))
                .set(DriverRegionServiceArrangement::getUpdatedAt, new Date())
                .update();
        primaryCachePutter.deleteDriverServiceArrangement();
        operationRecordHelper.addBusinessLog(String.format("修改了手续费规则 [%s][%s]", id, wrapper));
        return RestResult.success();
    }

    @Override
    public RestResult delete(AdminUser adminUser, Long id) {
        DriverRegionServiceArrangement arrangement = driverRegionServiceArrangementMapper.selectByCategoryAndId(DriverRegionServiceArrangementCategory.fee_rate, id);
        if (Objects.isNull(arrangement)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        driverRegionServiceArrangementMapper.deleteById(id);
        primaryCachePutter.deleteDriverServiceArrangement();
        operationRecordHelper.addBusinessLog(String.format("删除手续费规则 [%s]", arrangement));
        return RestResult.success();
    }
}
